-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Don't assemble non-env/bound candidates if projection is rigid #139762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Some changes occurred to the core trait solver cc @rust-lang/initiative-trait-system-refactor |
compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
Outdated
Show resolved
Hide resolved
This PR has two separate effects
I feel 🤷 about the first case. I think we should fix #139788 regardless as using RPITITs recursively shouldn't cycle even if they are actually needed. It does match the behavior of the old solver so it feels generally reasonable to do so. The second one is a bit worrying. I would be opposed/far more hesitant if it were to do the same when assembling trait goals as that definitely has an exponential performance impact (e.g. it would fix rust-lang/trait-system-refactor-initiative#109). I want to be very careful here as I expect us to consider impl candidates in more cases in the future and ideally doing so won't introduce new hangs :< I expect that in theory we may have exponential performance differences depending on whether or not we check impl item bounds. I don't know if they are likely enough to actually cause issues for us in the future. I am still a bit on the fence about this PR, but generally in favor I think. |
Well part of the point of this approach is we're already doing all the work of proving the trait goal in order to even compute the Totally unrelated side-note that it would be nice if query cycles were recoverable, lol. |
☔ The latest upstream changes (presumably #139845) made this pull request unmergeable. Please resolve the merge conflicts. |
yeah, exactly, the only hangs we'd be avoiding this way are due to GAT bounds. I guess this seems acceptable to me, so yeah. Let's go ahead with this change |
55069b6
to
513ace6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an alternative structure would be to change assemble_and_evaluate_candidates
to also take
enum AssembledCandidates {
All,
/// Only assemble candidates from the environment,
/// ignoring impls. We only look for `ParamEnv` and
/// `AliasBound` candidates.
FromEnv,
}
and then put assemble_impl_candidates
behind an if/match 🤔
I feel like splitting assembly into multiple functions is making this a bit harder to reason about.
thoughts?
Yeah, that would work too. |
513ace6
to
f7098be
Compare
inject_normalize_to_rigid_candidate: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>, | ||
) -> QueryResult<I> { | ||
let Some(proven_via) = proven_via else { | ||
// We don't care about overflow. If proving the trait goal overflowed, then | ||
// it's enough to report an overflow error for that, we don't also have to | ||
// overflow during normalization. | ||
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Ambiguity)); | ||
return Ok(self.forced_ambiguity(MaybeCause::Ambiguity)?.result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any case where make_ambiguous_response_no_constraints
was causing issues? or just general consistency. Also isn't this just return self.forced_ambiguity()
? :<
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any case where make_ambiguous_response_no_constraints was causing issues?
make_ambiguous_response_no_constraints
was causing us not to register a candidate kind, which is the reason why I had commented out that assertion in the BestObligation
folder above.
I prefer just actually assembling a built-in candidate for ambiguity here, but if you care a lot about this then we could just remove the assertion I linked above, but it does mean unnecessarily stepping into the "search for failures due to no candidates assembled" code in the best obligation folder.
lso isn't this just return self.forced_ambiguity()? :<
Nope, since we need to unwrap the candidate and return its query response.
i.e. return Ok(x?.field)
is not return x
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return x.map(|c| c.result)
then?
f7098be
to
39a8eca
Compare
[DO NOT MERGE] bootstrap with `-Znext-solver=globally` A revival of rust-lang#124812. Current status: ~~`./x.py b --stage 2` passes 🎉~~ `try` builds succeed 🎉 🎉 🎉 [top 100 most downloaded crates on crates.io compile](rust-lang#133502 (comment)) [first perf run](rust-lang#133502 (comment)) 👻 ### in-flight changes - rust-lang#124852, unsure whether I actually want to land this PR for now - rust-lang#139587 - https://github.com/lcnr/rust/tree/opaque-type-method-call - rust-lang#138845 - rust-lang#139762 - double the available recursion depth in the new solver ☠️ r? `@ghost`
39a8eca
to
e882ff4
Compare
[DO NOT MERGE] bootstrap with `-Znext-solver=globally` A revival of rust-lang#124812. Current status: ~~`./x.py b --stage 2` passes 🎉~~ `try` builds succeed 🎉 🎉 🎉 ~~[top 100 most downloaded crates on crates.io compile](rust-lang#133502 (comment) [top 1000 most downloaded crates on crates.io compile](rust-lang#133502 (comment)) [first perf run](rust-lang#133502 (comment)) 👻 ### in-flight changes - rust-lang#124852, unsure whether I actually want to land this PR for now - rust-lang#139587 - https://github.com/lcnr/rust/tree/opaque-type-method-call - rust-lang#138845 - rust-lang#139762 - double the available recursion depth in the new solver ☠️ r? `@ghost`
[DO NOT MERGE] bootstrap with `-Znext-solver=globally` A revival of rust-lang#124812. Current status: ~~`./x.py b --stage 2` passes 🎉~~ `try` builds succeed 🎉 🎉 🎉 ~~[top 100 most downloaded crates on crates.io compile](rust-lang#133502 (comment) [top 1000 most downloaded crates on crates.io compile](rust-lang#133502 (comment)) [first perf run](rust-lang#133502 (comment)) 👻 ### in-flight changes - rust-lang#124852, unsure whether I actually want to land this PR for now - rust-lang#139587 - https://github.com/lcnr/rust/tree/opaque-type-method-call - rust-lang#138845 - rust-lang#139762 - double the available recursion depth in the new solver ☠️ r? `@ghost`
@bors r+ rollup |
…enton Rollup of 8 pull requests Successful merges: - rust-lang#138934 (support config extensions) - rust-lang#139091 (Rewrite on_unimplemented format string parser.) - rust-lang#139753 (Make `#[naked]` an unsafe attribute) - rust-lang#139762 (Don't assemble non-env/bound candidates if projection is rigid) - rust-lang#139834 (Don't canonicalize crate paths) - rust-lang#139868 (Move `pal::env` to `std::sys::env_consts`) - rust-lang#139978 (Add citool command for generating a test dashboard) - rust-lang#139995 (Clean UI tests 4 of n) r? `@ghost` `@rustbot` modify labels: rollup
…enton Rollup of 8 pull requests Successful merges: - rust-lang#138934 (support config extensions) - rust-lang#139091 (Rewrite on_unimplemented format string parser.) - rust-lang#139753 (Make `#[naked]` an unsafe attribute) - rust-lang#139762 (Don't assemble non-env/bound candidates if projection is rigid) - rust-lang#139834 (Don't canonicalize crate paths) - rust-lang#139868 (Move `pal::env` to `std::sys::env_consts`) - rust-lang#139978 (Add citool command for generating a test dashboard) - rust-lang#139995 (Clean UI tests 4 of n) r? `@ghost` `@rustbot` modify labels: rollup
…enton Rollup of 8 pull requests Successful merges: - rust-lang#138934 (support config extensions) - rust-lang#139091 (Rewrite on_unimplemented format string parser.) - rust-lang#139753 (Make `#[naked]` an unsafe attribute) - rust-lang#139762 (Don't assemble non-env/bound candidates if projection is rigid) - rust-lang#139834 (Don't canonicalize crate paths) - rust-lang#139868 (Move `pal::env` to `std::sys::env_consts`) - rust-lang#139978 (Add citool command for generating a test dashboard) - rust-lang#139995 (Clean UI tests 4 of n) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#139762 - compiler-errors:non-env, r=lcnr Don't assemble non-env/bound candidates if projection is rigid Putting this up for an initial review, it's still missing comments, clean-up, and possibly a tweak to deal with ambiguities in the `BestObligation` folder. This PR fixes rust-lang/trait-system-refactor-initiative#173. Specifically, we're creating an unnecessary query cycle in normalization by assembling an *impl candidate* even if we know later on during `merge_candidates` that we'll be filtering out that impl candidate. This PR adjusts the `merge_candidates` to assemble *only* env/bound candidates if we have `TraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound`. I'll leave some thoughts/comments in the code. r? lcnr
…enton Rollup of 8 pull requests Successful merges: - rust-lang#138934 (support config extensions) - rust-lang#139091 (Rewrite on_unimplemented format string parser.) - rust-lang#139753 (Make `#[naked]` an unsafe attribute) - rust-lang#139762 (Don't assemble non-env/bound candidates if projection is rigid) - rust-lang#139834 (Don't canonicalize crate paths) - rust-lang#139868 (Move `pal::env` to `std::sys::env_consts`) - rust-lang#139978 (Add citool command for generating a test dashboard) - rust-lang#139995 (Clean UI tests 4 of n) r? `@ghost` `@rustbot` modify labels: rollup
Putting this up for an initial review, it's still missing comments, clean-up, and possibly a tweak to deal with ambiguities in the
BestObligation
folder.This PR fixes rust-lang/trait-system-refactor-initiative#173. Specifically, we're creating an unnecessary query cycle in normalization by assembling an impl candidate even if we know later on during
merge_candidates
that we'll be filtering out that impl candidate.This PR adjusts the
merge_candidates
to assemble only env/bound candidates if we haveTraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound
.I'll leave some thoughts/comments in the code.
r? lcnr